<?php
/************************************************************
 * 定义 MC_HtmlSymbol(HTML Container 改名了) 类
 * 这个是在html页面中的各种容器，比如div、P等等
 * 参考java中各种组件的那个思想，所有的东西（比如窗体、按钮等）都是由组件派生出来的
 * 在显示具体的内容的时候，由于html的结构可以看成是一个树形的结构，所以，为了存储的方便
 * 这里，将html中的各个元素/节点组织成二叉树的形式。每一个MC_HtmlSymbol类包含两个指针
 * 一个是儿子指针（左子树），一个是兄弟指针（右子树）。比如如下的结构：
 *        html                              html
 *       /   \                              /
 *  head    body      转化为二叉树       head
 *   /     /    \    ==============>     /  \
 * title div0    div1                title  body
 *       /\     /  |  \                     /
 *     p01 p02 p11 img12 p13               div0
 *                                        /    \
 *                                      p01   div1
 *                                       \     /
 *                                       p02 p11
 *                                             \
 *                                            img12
 *                                               \
 *                                               p13 
 *
 * 而在显示具体内容的时候，子标记应该是被包含在父标记里面的
 *
 * update: 2012-04-09
 *         修改setSon和setBrother方法，支持数组方式添加
 *         添加静态方法，传入一个二维的数组，生成一个表格
 ************************************************************/

class MC_HtmlSymbol extends MC_Base{

    /**
     * 定义非成对出现html标记的数组
     * @const array
     */

    var $html_sigle_obj = array('br','img', 'meta', 'link', 'input');

    /**
     * 定义html行内元素的数组
     * @const array
     */

    var $html_inline_obj = array('a', 'span', 'font');


    /**
     * 存放这个HTML 容器中存放的容器的名称
     * @var String
     */
 
    var $html_obj_name;

    /**
     * 当前容器的id，用于CSS
     * @var string
     */

    var $html_obj_css_id;

    /**
     * 当前容器的类名，用于CSS
     * @var string
     */

    var $html_obj_css_class;

    /**
     * 存放其它可能需要添加的html编码内容
     * @var string
     */
    
    var $html_obj_plus_code = '';


    /**
     * 存放当前容器中存放的具体的内容
     * @var string
     */

    var $content = '';


    /**
     * 存放当前容器包含的其他容器
     * @var MC_HtmlSymbol
     */

    var $son = null;



    /**
     * 存放当前容器的兄弟
     * @var MC_HtmlSymbol
     */

    var $brother = null;

    /**
     * 构造函数
     * @param string
     * @default = div
     */
    public function __construct($_name =  'div', $_id = '', $_css_class = ''){
        $this->html_obj_name = strtolower($_name);
        $this->html_obj_css_id = $_id;
        $this->html_obj_css_class = $_css_class;
    }

    /**
     * 设置容器内容
     * @param string 
     */
    
    public function setContent($_content = ''){
        if($_content != ''){
            $this->content = $_content;
        }
    } 

    /**
     * 设置儿子容器
     * @mixed  html_obj_name 或者 array
     *         当参数为 html_obj 数组时，数组中的元素之间为兄弟关系
     */
    
    public function setSon($_son = null){
        //处理数组的添加
        if(is_array($_son) && !empty($_son)){
            $start = array_shift($_son);
            $start->setBrother($_son);
            $this->son = $start;

        }else if($_son != null){

            $this->son = $_son;
        }
    } 

    /**
     * 设置兄弟容器
     * @param MC_HtmlSymbol_obj
     */

    public function setBrother($_brother = null){

        //处理数组的添加
        if(is_array($_brother) && !empty($_brother)){
            $start = array_shift($_brother);
            $this->brother = $start;
            while(null != ($tmp = array_shift($_brother))){
                $start->setBrother($tmp);
                $start = $tmp;
            }
        }else if($_brother != null){
            $this->brother = $_brother;
        }
    }

    /**
     * 取得容器内容
     * @return string 
     */
    public function getContent(){
        return $this->content;
    } 


    /**
     * 设置儿子容器
     * @return  html_obj_name
     */
    
    public function getSon(){
        return $this->son;
    } 

    /**
     * 设置兄弟容器
     * @return MC_HtmlSymbol_obj
     */

    public function getBrother(){
        return $this->brother;
    }

    /**
     * 设置css id
     * @param string 
     */
    public function setCSSid($_css_id = ''){
        $this->html_obj_css_id = $_css_id;
    }

    /**
     * 设置css class
     * @param string
     */
    public function setCSSclass($_css_class = ''){
        $this->html_obj_css_class = $_css_class;
    }

    /**
     * 设置其它添加的代码
     * @param string
     */
    public function setPluscode($_plus_code = ''){
        $this->html_obj_plus_code  = $_plus_code;
    }

    /**
     * 取得css id
     * @return string 
     */
    public function getCSSid(){
        return $this->html_obj_css_id;
    }

    /**
     * 根据标记的不同，生成标记代码，对于成对的标记，只生成前面的部分
     * @param null
     * @return string
     */
    private function getHTMLSign(){
        //存放临时代码
        $_html_code = '';

        //如果是开发模式，显示每个标记的说明
        //if($_SERVER['MCPHP_CONFIG']['Common']['HostEnv'] != 'prod')
        if(__get_config('Common.HostEnv') != 'prod')
            $_html_code = $this->html_obj_css_id?("\n".'<!--  '.$this->html_obj_css_id.' start  -->'."\n"):'';

        $_html_code .= '<'.$this->html_obj_name;
        if($this->html_obj_css_id != '')
            $_html_code .= ' id="'.$this->html_obj_css_id.'"';
        if($this->html_obj_css_class != '')
            $_html_code .= ' class="'.$this->html_obj_css_class.'"';
        if($this->html_obj_plus_code != '')
            $_html_code .= ' '.$this->html_obj_plus_code;
 
        //判断当前的容器是否是单标签
        //单标签就做显示
        if(in_array($this->html_obj_name, $this->html_sigle_obj)){
            $_html_code .= ' />'."\n";
        }else{
            $_html_code .= '>';
        }

        return $_html_code;

    }

    
    /**
     * 显示当前容器的内容
     * @param null
     */

    public function display(){
        echo $this->getHTMLCode();
    }


    /**
     * 显示当前容器和兄弟容器内容
     * @param null
     */

    public function displayAll(){
        echo $this->getCompleteCode();
    }


    /**
     * 取得当前容器中的内容和标签
     * 这个得到的只有当前容器和当前容器子容器的内容，并不会返回兄弟容器的内容
     * 就是说，只有自己和左子树的内容（见上面说明的图）
     * @param null
     * @return string
     */

    public function getHTMLCode(){
        //存放临时代码，并取得当前的标签
        $_html_code = $this->getHTMLSign();

        //当前容器的内容
        $_html_code .= $this->content;

        //子容器内容
        if($this->son != null){
            $_html_code .= $this->son->getCompleteCode();
        }

        //判断当前的容器是否是成对标签
        if(!in_array($this->html_obj_name, $this->html_sigle_obj)){
            $_html_code .= '</'.$this->html_obj_name.'>';
            //判断是否是行内原素
            if(!in_array($this->html_obj_name, $this->html_inline_obj))
                 $_html_code .= "\n";
        }

        //如果是开发模式，显示每个标记的说明
        //if($_SERVER['MCPHP_CONFIG']['Common']['HostEnv'] != 'prod')
        if(__get_config('Common.HostEnv') != 'prod')
            $_html_code .= $this->html_obj_css_id?('<!--  '.$this->html_obj_css_id.' end  -->'."\n"):'';


        return $_html_code;

    }


    /**
     * 取得当前容器的html代码，包括兄弟容器的内容
     * 先返回自身代码，再返回兄弟代码
     * 从上面的图可以看出，这个只能返回当前容器的弟容器的内容（右子树）
     * 而兄容器和父容器（当前容器的上一级）是无法返回内容的
     * @param null
     * @return String 
     */

    public function getCompleteCode(){

        //存放临时代码，并取得当前容器内容
        $_html_code = $this->getHTMLCode();

        //获取兄弟容器内容
        if($this->brother != null)
            $_html_code .= $this->brother->getCompleteCode();

        return $_html_code;
    }

    /**
     * 常用HTML元素的创建方法
     * @param string string
     * @return MC_HtmlSymbol
     */

    static public function CreateMeta( $_meta ){
        $_obj_meta = new MC_HtmlSymbol('meta');
        $_obj_meta->setPluscode($_meta);
        return $_obj_meta;
    }

    static public function CreateLink( $_link ){
        $_obj_link = new MC_HtmlSymbol('link');
        $_obj_link->setPluscode($_link);
        return $_obj_link;
    }

    static public function CreateScript( $_script ){
        $_obj_script = new MC_HtmlSymbol('script');
        $_obj_script->setPluscode($_script);
        return $_obj_script;
    }

    static public function CreateTitle( $_title ){
        $_obj_title = new MC_HtmlSymbol('title');
        if($_title != '')
            $_obj_title->setContent($_title);
        else
            $_obj_title->setContent('无标题文档');
        return $_obj_title;
    }

    static public function CreateDiv( $_id = '', $_css_class = ''){
        return new MC_HtmlSymbol( 'div', $_id, $_css_class );
    }

    static public function CreateP( $_content='', $_id = '', $_css_class = ''){
        $_obj_p = new MC_HtmlSymbol( 'p', $_id, $_css_class );
        if($_content != '')
            $_obj_p->setContent($_content);
        return $_obj_p;
    }

    static public function CreateImg( $_src, $_id = '', $_css_class = ''){
        $_obj_img = new MC_HtmlSymbol('img', $_id, $_css_class);
        $_obj_img->setPluscode($_src);
        return $_obj_img;
    }

    static public function CreateA( $_href='', $_content='', $_id = '', $_css_class = ''){
        $_obj_a = new MC_HtmlSymbol('a', $_id, $_css_class);
        if($_content != '')
            $_obj_a->setContent($_content);
        else
            $_obj_a->setContent($_href);
        $_obj_a->setPluscode($_href);
        return $_obj_a;
    }

    static public function CreateH1( $_id = '', $_css_class = ''){
        return new MC_HtmlSymbol( 'h1', $_id, $_css_class );
    }

    static public function CreateH2( $_id = '', $_css_class = ''){
        return new MC_HtmlSymbol( 'h2', $_id, $_css_class );
    }

    static public function CreateH3( $_id = '', $_css_class = ''){
        return new MC_HtmlSymbol( 'h3', $_id, $_css_class );
    }

    static public function CreateHTML(){
        return new MC_HtmlSymbol( 'html' );
    }

    static public function CreateHead(){
        return new MC_HtmlSymbol( 'head' );
    }

    static public function CreateBody($_id = '', $_css_class = ''){
        return new MC_HtmlSymbol( 'body', $_id, $_css_class );
    }

    static public function CreateHtmlSym( $_name, $_id = '', $_css_class = ''){
        return new MC_HtmlSymbol( $_name, $_id, $_css_class );
    }
    
    //给定一个二维数组，生成一个表格
    //$_data 二维数组
    //$_id 表（table）对应的id
    //$_plus_code 表其他的属性的设置
    //$_tr_plus_code 表中每一行的标签（tr）的plus_code，使用数组，按数组的顺序依次添加
    //$_row_title 表的标题行，数组
    //$_tab_title 表的标题
    static public function CreateTab( $_data, $_id = '', $_plus_code = '', $_tr_plus_code = array(), $_col_title = null, $_tab_title = null){
                
        $table = new MC_HtmlSymbol('table', $_id);
        $table->setPluscode($_plus_code);
        
        $tab_code = '';
        
        //设置标题
        if(null != $_tab_title )
            $tab_code .= "<caption>$_tab_title</caption>\n";
        
        //设置列标题
        if(is_array($_col_title) && !empty($_col_title)){
            $tab_code .= "<tr>\n";
            foreach($_col_title as $_ct){
                $tab_code .= "<th>$_ct</th>\n";
            }
            $tab_code .= "</tr>\n";
        }
        
        //处理表格中的数据
        //如果需要设置行的附加属性
        $_size_of_plus_code = 0;
        if(is_array($_tr_plus_code) && !empty($_tr_plus_code)){
            $_size_of_plus_code = count($_tr_plus_code);
        }
        $i = 0;
        foreach($_data as $_tr){
            if(!$_size_of_plus_code){
                $tab_code .= "<tr>\n";
            }else{
                $tab_code .= "<tr ".($_tr_plus_code[$i++ % $_size_of_plus_code])." >\n";
            }
            foreach ($_tr as $_td){
                $tab_code .= "<td>$_td</td>\n";
            }
            $tab_code .= "</tr>\n";
        }
        
        $table->setContent($tab_code);

        return $table;
    }

};
